package com.server.db.jedis;

import java.util.ArrayList;
import com.sandking.config.SK_Config;
import java.util.Map;
import com.sandking.tools.SK_Plus;
import java.util.List;
import com.sandking.tools.SK_String;
import java.util.Collections;
import com.sandking.tools.SK_List;
import java.util.Comparator;
import com.server.db.DbLock;
import com.sandking.constant.SK_ErrorCode;
import com.sandking.tools.SK_PageCount;
import com.server.db.bean.Yh;
import java.util.concurrent.locks.ReentrantLock;
import java.util.Set;
import com.sandking.tools.SK_Exception;
import redis.clients.jedis.Pipeline;
import redis.clients.jedis.Jedis;
/**
 * 用户
 * 1.做为Jedis单独使用的情况，我是不建议的!他不能保证线程安全性问题，没有数据补救的操作
 * 2.jedis的查询数据是没有顺序的
 */
public class YhJedis{
	static class YhSore implements Comparator<Yh> {
		@Override
		public int compare(Yh yh1, Yh yh2) {
			if (yh1.getId() > yh2.getId())
				return 1;
			else if (yh1.getId() < yh2.getId())
				return -1;
			else {
				return 0;
			}
		}
	}
	//表锁(重入锁)
	static final ReentrantLock tableLock = new ReentrantLock();
	
	static Comparator<Yh> comparator = new YhSore();
	
	/**
	 * 根据( id ) 查询
	 */
	public static Yh getById(int id){
		Jedis jedis = SK_Config.getJedisPoll().getResource();
		Yh yh = null;
		try{
			String key = "Yh_Object";
			String field = SK_Plus.b("id:",id).e();
			String json = jedis.hget(key,field);
			if(!SK_String.isEmpty(json))
				yh = Yh.createForJson(json);
		}finally{
			 SK_Config.getJedisPoll().returnResource(jedis);
		}
		return yh;
	}
	
	public static List<Yh> getByIdIn(int[] ids){
		Jedis jedis = SK_Config.getJedisPoll().getResource();
		List<Yh> yhs = new ArrayList<Yh>();
		try{
			String key = "Yh_Object";
			String[] strIds = new String[ids.length];
			for (int i = 0; i < strIds.length; i++) {
				strIds[i] = String.valueOf(ids[i]);
			}
			List<String> jsons = jedis.hmget(key,strIds);
			 yhs = Yh.createForJson(jsons);
		}catch (Exception e) {
			
		}finally{
			 SK_Config.getJedisPoll().returnResource(jedis);
		}
		return yhs;
	}
	/**
	 * 根据( 昵称 ) 查询
	 */
	public static Yh getByNc(String nc){
		Jedis jedis = SK_Config.getJedisPoll().getResource();
		Yh yh = null;
		try{
			String key = "Yh_Index";
			String field = SK_Plus.b("nc:",nc).e();
			String primaryKey = jedis.hget(key,field);
			if(primaryKey!=null){
				yh = getById(Integer.valueOf(primaryKey));
			}
		}finally{
			 SK_Config.getJedisPoll().returnResource(jedis);
		}
		return yh;
	}
	
	/**
	 * 根据( 账号 ) 查询
	 */
	public static Yh getByZh(String zh){
		Jedis jedis = SK_Config.getJedisPoll().getResource();
		Yh yh = null;
		try{
			String key = "Yh_Index";
			String field = SK_Plus.b("zh:",zh).e();
			String primaryKey = jedis.hget(key,field);
			if(primaryKey!=null){
				yh = getById(Integer.valueOf(primaryKey));
			}
		}finally{
			 SK_Config.getJedisPoll().returnResource(jedis);
		}
		return yh;
	}
	
	/**
	 * 根据( 账号  密码 ) 查询
	 */
	public static Yh getByZhMm(String zh, String mm){
		Jedis jedis = SK_Config.getJedisPoll().getResource();
		Yh yh = null;
		try{
			String key = "Yh_Index";
			String field = SK_Plus.b("zh,mm:",zh,"_",mm).e();
			String primaryKey = jedis.hget(key,field);
			if(primaryKey!=null){
				yh = getById(Integer.valueOf(primaryKey));
			}
		}finally{
			 SK_Config.getJedisPoll().returnResource(jedis);
		}
		return yh;
	}
	
	/**
	 * 根据( 用户类型_id ) 查询
	 */
	public static List<Yh> getByYhlx_id(int yhlx_id){
		Jedis jedis = SK_Config.getJedisPoll().getResource();
		List<Yh> yhs = new ArrayList<Yh>();
		try{
			String key = "Yh_Index";
			String field = SK_Plus.b(key,"yhlx_id:",yhlx_id).e();
			Set<String> setStr = jedis.smembers(field);
			if(setStr!=null){
				key = "Yh_Object";
				String[] fieldArray = (String[]) setStr.toArray();
				List<String> jsons = jedis.hmget(key,fieldArray);
				yhs = Yh.createForJson(jsons);
			}
		}finally{
			 SK_Config.getJedisPoll().returnResource(jedis);
		}
		Collections.sort(yhs, comparator);
		return yhs;
	}
	
	
	public static List<Yh> getByPageYhlx_id(int yhlx_id,int page,int size,SK_PageCount pageCount){
		List<Yh> yhs = getByYhlx_id(yhlx_id);
		yhs = SK_List.getPage(yhs, page, size, pageCount);
		return yhs;
	}
	
	/**
	 * 根据( 服务器_id ) 查询
	 */
	public static List<Yh> getByFwq_id(int fwq_id){
		Jedis jedis = SK_Config.getJedisPoll().getResource();
		List<Yh> yhs = new ArrayList<Yh>();
		try{
			String key = "Yh_Index";
			String field = SK_Plus.b(key,"fwq_id:",fwq_id).e();
			Set<String> setStr = jedis.smembers(field);
			if(setStr!=null){
				key = "Yh_Object";
				String[] fieldArray = (String[]) setStr.toArray();
				List<String> jsons = jedis.hmget(key,fieldArray);
				yhs = Yh.createForJson(jsons);
			}
		}finally{
			 SK_Config.getJedisPoll().returnResource(jedis);
		}
		Collections.sort(yhs, comparator);
		return yhs;
	}
	
	
	public static List<Yh> getByPageFwq_id(int fwq_id,int page,int size,SK_PageCount pageCount){
		List<Yh> yhs = getByFwq_id(fwq_id);
		yhs = SK_List.getPage(yhs, page, size, pageCount);
		return yhs;
	}
	
	/**
	 * 根据( 渠道 ) 查询
	 */
	public static List<Yh> getByQd(String qd){
		Jedis jedis = SK_Config.getJedisPoll().getResource();
		List<Yh> yhs = new ArrayList<Yh>();
		try{
			String key = "Yh_Index";
			String field = SK_Plus.b(key,"qd:",qd).e();
			Set<String> setStr = jedis.smembers(field);
			if(setStr!=null){
				key = "Yh_Object";
				String[] fieldArray = (String[]) setStr.toArray();
				List<String> jsons = jedis.hmget(key,fieldArray);
				yhs = Yh.createForJson(jsons);
			}
		}finally{
			 SK_Config.getJedisPoll().returnResource(jedis);
		}
		Collections.sort(yhs, comparator);
		return yhs;
	}
	
	
	public static List<Yh> getByPageQd(String qd,int page,int size,SK_PageCount pageCount){
		List<Yh> yhs = getByQd(qd);
		yhs = SK_List.getPage(yhs, page, size, pageCount);
		return yhs;
	}
	
	/**
	 * 根据( 联盟_id ) 查询
	 */
	public static List<Yh> getByLm_id(int lm_id){
		Jedis jedis = SK_Config.getJedisPoll().getResource();
		List<Yh> yhs = new ArrayList<Yh>();
		try{
			String key = "Yh_Index";
			String field = SK_Plus.b(key,"lm_id:",lm_id).e();
			Set<String> setStr = jedis.smembers(field);
			if(setStr!=null){
				key = "Yh_Object";
				String[] fieldArray = (String[]) setStr.toArray();
				List<String> jsons = jedis.hmget(key,fieldArray);
				yhs = Yh.createForJson(jsons);
			}
		}finally{
			 SK_Config.getJedisPoll().returnResource(jedis);
		}
		Collections.sort(yhs, comparator);
		return yhs;
	}
	
	
	public static List<Yh> getByPageLm_id(int lm_id,int page,int size,SK_PageCount pageCount){
		List<Yh> yhs = getByLm_id(lm_id);
		yhs = SK_List.getPage(yhs, page, size, pageCount);
		return yhs;
	}
	
	/**
	 * 根据( 渠道  用户类型_id ) 查询
	 */
	public static List<Yh> getByQdYhlx_id(String qd, int yhlx_id){
		Jedis jedis = SK_Config.getJedisPoll().getResource();
		List<Yh> yhs = new ArrayList<Yh>();
		try{
			String key = "Yh_Index";
			String field = SK_Plus.b(key,"qd,yhlx_id:",qd,"_",yhlx_id).e();
			Set<String> setStr = jedis.smembers(field);
			if(setStr!=null){
				key = "Yh_Object";
				String[] fieldArray = (String[]) setStr.toArray();
				List<String> jsons = jedis.hmget(key,fieldArray);
				yhs = Yh.createForJson(jsons);
			}
		}finally{
			 SK_Config.getJedisPoll().returnResource(jedis);
		}
		Collections.sort(yhs, comparator);
		return yhs;
	}
	
	
	public static List<Yh> getByPageQdYhlx_id(String qd, int yhlx_id,int page,int size,SK_PageCount pageCount){
		List<Yh> yhs = getByQdYhlx_id(qd,yhlx_id);
		yhs = SK_List.getPage(yhs, page, size, pageCount);
		return yhs;
	}
	

	public static List<Yh> getAll(){
		Jedis jedis = SK_Config.getJedisPoll().getResource();
		List<Yh> yhs = new ArrayList<Yh>();
		try{
			String key = "Yh_Object";
			List<String> jsons = jedis.hvals(key);
			yhs = Yh.createForJson(jsons);
		}finally{
			 SK_Config.getJedisPoll().returnResource(jedis);
		}
		Collections.sort(yhs, comparator);
		return yhs;
	}
	
	
	public static List<Yh> getAllByPage(int page,int size,SK_PageCount pageCount){
		List<Yh> yhs = getAll();
		yhs = SK_List.getPage(yhs, page, size, pageCount);
		return yhs;
	}
	
	
	public static Yh putData(Yh yh,Pipeline p,int type) throws SK_Exception{
		boolean isLock = (type == SK_Config.CHECK_ALL_INDEX);
		Map<String,String> updateIndexs = null;
		if(type == SK_Config.CHECK_UPDATE_INDEX){
			updateIndexs = yh.getUpdateIndexs();
			isLock = updateIndexs.containsKey("isUpdtaeUnique");
		}
		try{
			DbLock.lock(yh.getId(),DbLock.yh_locks);
			if(isLock)tableLock.lock();
			switch (type) {
			case SK_Config.CHECK_ALL_INDEX:
				checkUniqueIndex(yh);
				break;
			case SK_Config.CHECK_UPDATE_INDEX:
				checkUniqueIndex(updateIndexs);
				break;
			}
			if(type == SK_Config.CHECK_UPDATE_INDEX){
				removeData(yh);
			}
			// ---------------------- 主键索引 ----------------------
			String key = "Yh_Object";
			String field = SK_Plus.b("id:",yh.getId()).e();
			String data = yh.toJson();
			p.hset(key,field,data);
			
			// ---------------------- 唯一索引 ----------------------
			String primaryKey = String.valueOf(yh.getId());
			key = "Yh_Index";
			
			field = SK_Plus.b("nc:",yh.getNc()).e();
			p.hset(key,field,primaryKey);
			
			field = SK_Plus.b("zh:",yh.getZh()).e();
			p.hset(key,field,primaryKey);
			
			field = SK_Plus.b("zh,mm:",yh.getZh(),"_",yh.getMm()).e();
			p.hset(key,field,primaryKey);
			
			// ---------------------- 聚集索引 ----------------------
			field = SK_Plus.b(key,"yhlx_id:",yh.getYhlx_id()).e();
			p.sadd(field, primaryKey);
			
			field = SK_Plus.b(key,"fwq_id:",yh.getFwq_id()).e();
			p.sadd(field, primaryKey);
			
			field = SK_Plus.b(key,"qd:",yh.getQd()).e();
			p.sadd(field, primaryKey);
			
			field = SK_Plus.b(key,"lm_id:",yh.getLm_id()).e();
			p.sadd(field, primaryKey);
			
			field = SK_Plus.b(key,"qd,yhlx_id:",yh.getQd(),"_",yh.getYhlx_id()).e();
			p.sadd(field, primaryKey);
			
		}finally{
			 DbLock.unlock(yh.getId(),DbLock.yh_locks);
			 if(isLock)tableLock.unlock();
		}
		return yh;
	}
	
	public static List<Yh> putDataAll(List<Yh> yhs,int type){
		Jedis jedis = SK_Config.getJedisPoll().getResource();
		List<Yh> yhs_ = new ArrayList<Yh>();
		try{
			Pipeline p = jedis.pipelined();
			for(Yh yh : yhs){
				try {
					yhs_.add(putData(yh,p,type));
				} catch (SK_Exception e) {
					e.printStackTrace();
				}
			}
			p.sync();
		}finally{
			 SK_Config.getJedisPoll().returnResource(jedis);
		}
		return yhs_;
	}
	
	public static void removeData(Yh yh){
		Jedis jedis = SK_Config.getJedisPoll().getResource();
		try{
			Pipeline p = jedis.pipelined();
			removeData(yh,p);
			p.sync();
		}finally{
			 SK_Config.getJedisPoll().returnResource(jedis);
		}
	}
	
	/**
	 * 清空一个缓存
	 */
	public static void removeData(Yh yh,Pipeline p){
		try{
			DbLock.lock(yh.getId(),DbLock.yh_locks);
			// ---------------------- 主键索引 ----------------------
			String key = "Yh_Object";
			String field = SK_Plus.b("id:",yh.getId_Unique()).e();
			p.hdel(key,field);
			
			// ---------------------- 唯一索引 ----------------------
			key = "Yh_Index";
			
			field = SK_Plus.b("nc:",yh.getNc_Unique()).e();
			if(field!=null){
				p.hdel(key,field);
			}
			field = SK_Plus.b("zh:",yh.getZh_Unique()).e();
			if(field!=null){
				p.hdel(key,field);
			}
			field = SK_Plus.b("zh,mm:",yh.getZhMm_Unique()).e();
			if(field!=null){
				p.hdel(key,field);
			}
			// ---------------------- 聚集索引 ----------------------
			String primaryKey = String.valueOf(yh.getId());
			field = SK_Plus.b(key,"yhlx_id:",yh.getYhlx_id_Index()).e();
			p.srem(field, primaryKey);
			
			field = SK_Plus.b(key,"fwq_id:",yh.getFwq_id_Index()).e();
			p.srem(field, primaryKey);
			
			field = SK_Plus.b(key,"qd:",yh.getQd_Index()).e();
			p.srem(field, primaryKey);
			
			field = SK_Plus.b(key,"lm_id:",yh.getLm_id_Index()).e();
			p.srem(field, primaryKey);
			
			field = SK_Plus.b(key,"qd,yhlx_id:",yh.getQdYhlx_id_Index()).e();
			p.srem(field, primaryKey);
			
		}finally{
			 DbLock.unlock(yh.getId(),DbLock.yh_locks);
		}
	}

	public static void removeDataAll(List<Yh> yhs){
		Jedis jedis = SK_Config.getJedisPoll().getResource();
		try{
			Pipeline p = jedis.pipelined();
			for(Yh yh : yhs){
				removeData(yh,p);
			}
			p.sync();
		}finally{
			 SK_Config.getJedisPoll().returnResource(jedis);
		}
	}
	
	public static Yh insert(Yh yh){
		Jedis jedis = SK_Config.getJedisPoll().getResource();
		Jedis jedisPipeline = SK_Config.getJedisPoll().getResource();
		Pipeline p = jedisPipeline.pipelined();
		try{
			if(yh.getId() < 1){
				try {
					tableLock.lock();
					yh.setId(jedis.hincrBy("primaryKey", Yh.CLASS_NAME,1).intValue());
				}finally{
					tableLock.unlock();
				}
			}
			DbLock.lock(yh.getId(),DbLock.yh_locks);
			try {
				yh = putData(yh, p, SK_Config.CHECK_ALL_INDEX);
				p.sync();
				return yh;
			} catch (SK_Exception e) {
				e.printStackTrace();
			}
    	}finally{
			 SK_Config.getJedisPoll().returnResource(jedis);
			 SK_Config.getJedisPoll().returnResource(jedisPipeline);
			 DbLock.unlock(yh.getId(),DbLock.yh_locks);
		}
		return null;
    }
    
    public static List<Yh> insertBatch(List<Yh> yhs){
    	Jedis jedis = SK_Config.getJedisPoll().getResource();
    	try{
			yhs = putDataAll(yhs, SK_Config.CHECK_ALL_INDEX);
			jedis.hincrBy("primaryKey", Yh.CLASS_NAME,yhs.size());
		}finally{
			 SK_Config.getJedisPoll().returnResource(jedis);
		}
    	return yhs;
    }
    
    public static Yh update(Yh yh){
    	Jedis jedis = SK_Config.getJedisPoll().getResource();
		Jedis jedisPipeline = SK_Config.getJedisPoll().getResource();
		Pipeline p = jedisPipeline.pipelined();
		try{
			DbLock.lock(yh.getId(),DbLock.yh_locks);
			try{
				yh = putData(yh,p,SK_Config.CHECK_UPDATE_INDEX);
				p.sync();
				return yh;
			} catch (SK_Exception e) {
				e.printStackTrace();
			}
    	}finally{
			 SK_Config.getJedisPoll().returnResource(jedis);
			 SK_Config.getJedisPoll().returnResource(jedisPipeline);
			 DbLock.unlock(yh.getId(),DbLock.yh_locks);
		}
		return null;
    }
    
    public static List<Yh> updateBatch(List<Yh> yhs){
    	removeDataAll(yhs);
		putDataAll(yhs,SK_Config.CHECK_UPDATE_INDEX);
    	return yhs;
    }
    
    public static boolean delete(Yh yh){
    	Jedis jedis = SK_Config.getJedisPoll().getResource();
		Jedis jedisPipeline = SK_Config.getJedisPoll().getResource();
		Pipeline p = jedisPipeline.pipelined();
		boolean bool = true;
		try{
			DbLock.lock(yh.getId(),DbLock.yh_locks);
	    	removeData(yh,p);
	    	p.sync();
	    }finally{
			 SK_Config.getJedisPoll().returnResource(jedis);
			 SK_Config.getJedisPoll().returnResource(jedisPipeline);
			 DbLock.unlock(yh.getId(),DbLock.yh_locks);
		}
	    return bool;
    }
    
    public static boolean deleteBatch(List<Yh> yhs){
    	boolean bool = true;
    	removeDataAll(yhs);
    	return bool;
    }
    
    
    
    //检查唯一索引
	private static void checkUniqueIndex(Yh yh) throws SK_Exception{
		Jedis jedis = SK_Config.getJedisPoll().getResource();
		try{
			tableLock.lock();
			String key = "Yh_Object";
			String field = SK_Plus.b("id:",SK_Plus.b(yh.getId()).e()).e();
			if(jedis.hexists(key,field))
				throw new SK_Exception(SK_ErrorCode.UNIQUE_INDEX_ERROR,SK_Plus.b(Yh.Id_IndexName,"=",field).e());
				
			key = "Yh_Index";
			field = SK_Plus.b("nc:",SK_Plus.b(yh.getNc()).e()).e();
			if(jedis.hexists(key,field))
				throw new SK_Exception(SK_ErrorCode.UNIQUE_INDEX_ERROR,SK_Plus.b(Yh.Nc_IndexName,"=",field).e());
				
			key = "Yh_Index";
			field = SK_Plus.b("zh:",SK_Plus.b(yh.getZh()).e()).e();
			if(jedis.hexists(key,field))
				throw new SK_Exception(SK_ErrorCode.UNIQUE_INDEX_ERROR,SK_Plus.b(Yh.Zh_IndexName,"=",field).e());
				
			key = "Yh_Index";
			field = SK_Plus.b("zh,mm:",SK_Plus.b(yh.getZh(),"_",yh.getMm()).e()).e();
			if(jedis.hexists(key,field))
				throw new SK_Exception(SK_ErrorCode.UNIQUE_INDEX_ERROR,SK_Plus.b(Yh.ZhMm_IndexName,"=",field).e());
				
		}finally{
			SK_Config.getJedisPoll().returnResource(jedis);
			tableLock.unlock();
		}
	}
	
	/** 检查(改变的)唯一索引 */
	private static void checkUniqueIndex(Map<String,String> indexs) throws SK_Exception{
		Jedis jedis = SK_Config.getJedisPoll().getResource();
		try{
			tableLock.lock();
			String key = "";
			for (Map.Entry<String, String> index : indexs.entrySet()) {
				switch (index.getKey()) {
				case Yh.Id_IndexName:
					key = "Yh_Object";
					if(jedis.hexists(key,SK_Plus.b("id:",index.getValue()).e()))
						throw new SK_Exception(SK_ErrorCode.UNIQUE_INDEX_ERROR,SK_Plus.b(Yh.Id_IndexName,"=",index.getValue()).e());
					break;
				case Yh.Nc_IndexName:
					key = "Yh_Index";
					if(jedis.hexists(key,SK_Plus.b("nc:",index.getValue()).e()))
						throw new SK_Exception(SK_ErrorCode.UNIQUE_INDEX_ERROR,SK_Plus.b(Yh.Nc_IndexName,"=",index.getValue()).e());
					break;
				case Yh.Zh_IndexName:
					key = "Yh_Index";
					if(jedis.hexists(key,SK_Plus.b("zh:",index.getValue()).e()))
						throw new SK_Exception(SK_ErrorCode.UNIQUE_INDEX_ERROR,SK_Plus.b(Yh.Zh_IndexName,"=",index.getValue()).e());
					break;
				case Yh.ZhMm_IndexName:
					key = "Yh_Index";
					if(jedis.hexists(key,SK_Plus.b("zh,mm:",index.getValue()).e()))
						throw new SK_Exception(SK_ErrorCode.UNIQUE_INDEX_ERROR,SK_Plus.b(Yh.ZhMm_IndexName,"=",index.getValue()).e());
					break;
				}
			}
		}finally{
			SK_Config.getJedisPoll().returnResource(jedis);
			tableLock.unlock();
		}
	}
}